# 获取上下文管理器单例
import json
import time

from functools import wraps

from utils.context.utils.out import clear_context, context_set, format_context_data


def api_context(service_name, logger=None):
    """
        初始化上下文的装饰器，在调用视图函数之前设置上下文环境
        service_name : 本次的服务名称，用于区分不同服务
        logger: 日志器实例
    """

    def decorator(func):

        @wraps(func)
        def wrapper(request, *args, **kwargs):
            _request = request.request
            # 清空旧的上下文数据
            clear_context()

            # 在此初始化新的上下文数据
            context_set('request_time', time.time())
            context_set('request_url', _request.path)
            context_set('service_name', service_name)

            # 如果有用户登录信息，可以将用户信息加入上下文
            if _request.user.is_authenticated:
                context_set('user_id', _request.user.id)
                context_set('username', _request.user.username)

            # 调用实际的视图函数
            try:
                response = func(request, *args, **kwargs)
            except Exception as e:
                context_set('error_message', str(e))
                raise e
            finally:
                if logger:
                    logger.info(json.dumps(format_context_data(), ensure_ascii=False))
                clear_context()
            return response

        return wrapper

    return decorator
